#include "ExampleApplication.h"

/// Standard constructor
ExampleApplication::ExampleApplication()
:mRoot(NULL), mFrameListener(NULL)
{
	mResourcePath = "";
	mConfigPath = mResourcePath;
}

/// Standard destructor
ExampleApplication::~ExampleApplication()
{
	if (mFrameListener)
		delete mFrameListener;
	if (mRoot)
		OGRE_DELETE mRoot;

}

/// Start the example
// void ExampleApplication::go(void)
// {
// 	if (!setup())
// 		return;
// 
// 	mRoot->startRendering();
// 
// 	// clean up
// 	destroyScene();	
// }

// These internal methods package up the stages in the startup process
/** Sets up the application - returns false if the user chooses to abandon configuration. */
bool ExampleApplication::setup(HWND hwnd, int width, int height, HWND mainWnd)
{

	String pluginsPath;

#if OGRE_DEBUG_MODE
	pluginsPath = mResourcePath + "plugins_d.cfg";
#else
	pluginsPath = mResourcePath + "plugins.cfg";
#endif


	mRoot = OGRE_NEW Root(pluginsPath, 
		mConfigPath + "ogre.cfg", mResourcePath + "Ogre.log");

	setupResources();

	bool carryOn = configure(hwnd, width, height);
	if (!carryOn) 
		return false;

	chooseSceneManager();
	createCamera();
	createViewports();

	// Set default mipmap level (NB some APIs ignore this)
	TextureManager::getSingleton().setDefaultNumMipmaps(5);

	// Create any resource listeners (for loading screens)
	createResourceListener();
	// Load resources
	loadResources();

	// Create the scene
	createScene();

	createFrameListener(mainWnd);

	return true;

}

/** Configures the application - returns false if the user chooses to abandon configuration. */
bool ExampleApplication::configure(HWND hwnd, int width, int height)
{
	// Show the configuration dialog and initialise the system
	// You can skip this and use root.restoreConfig() to load configuration
	// settings if you were sure there are valid ones saved in ogre.cfg
	if(mRoot->showConfigDialog())
	{
		// If returned true, user clicked OK so initialise
		// Here we choose to let the system create a default rendering window by passing 'true'
		//mWindow = mRoot->initialise(true);
		Ogre::NameValuePairList parms;
		parms["externalWindowHandle"] = Ogre::StringConverter::toString((long)hwnd);


		mWindow = mRoot->createRenderWindow("MFC Window", width, height, false, &parms);

		return true;
	}
	else
	{
		return false;
	}
}

void ExampleApplication::chooseSceneManager(void)
{
	// Create the SceneManager, in this case a generic one
	mSceneMgr = mRoot->createSceneManager(ST_GENERIC, "ExampleSMInstance");
}
void ExampleApplication::createCamera(void)
{
	// Create the camera
	mCamera = mSceneMgr->createCamera("PlayerCam");

	// Position it at 500 in Z direction
	mCamera->setPosition(Vector3(0,0,500));
	// Look back along -Z
	mCamera->lookAt(Vector3(0,0,-300));
	mCamera->setNearClipDistance(5);

}
void ExampleApplication::createFrameListener(HWND mainWnd)
{
	mFrameListener= new ExampleFrameListener(mWindow, mCamera, mainWnd);
	mFrameListener->showDebugOverlay(true);
	mRoot->addFrameListener(mFrameListener);
}


void ExampleApplication::destroyScene(void){}    // Optional to override this

void ExampleApplication::createViewports(void)
{
	// Create one viewport, entire window
	Viewport* vp = mWindow->addViewport(mCamera);
	vp->setBackgroundColour(ColourValue(0,0,0));

	// Alter the camera aspect ratio to match the viewport
	mCamera->setAspectRatio(
		Real(vp->getActualWidth()) / Real(vp->getActualHeight()));
}

/// Method which will define the source of resources (other than current folder)
void ExampleApplication::setupResources(void)
{
	// Load resource paths from config file
	ConfigFile cf;
#if OGRE_DEBUG_MODE
	cf.load(mResourcePath + "resources_d.cfg");
#else
	cf.load(mResourcePath + "resources.cfg");
#endif

	// Go through all sections & settings in the file
	ConfigFile::SectionIterator seci = cf.getSectionIterator();

	String secName, typeName, archName;
	while (seci.hasMoreElements())
	{
		secName = seci.peekNextKey();
		ConfigFile::SettingsMultiMap *settings = seci.getNext();
		ConfigFile::SettingsMultiMap::iterator i;
		for (i = settings->begin(); i != settings->end(); ++i)
		{
			typeName = i->first;
			archName = i->second;

			ResourceGroupManager::getSingleton().addResourceLocation(
				archName, typeName, secName);

		}
	}
}

/// Optional override method where you can create resource listeners (e.g. for loading screens)
void ExampleApplication::createResourceListener(void)
{

}

/// Optional override method where you can perform resource group loading
/// Must at least do ResourceGroupManager::getSingleton().initialiseAllResourceGroups();
void ExampleApplication::loadResources(void)
{
	// Initialise, parse scripts etc
	ResourceGroupManager::getSingleton().initialiseAllResourceGroups();

}